package com.gzmu.face.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gzmu.face.entity.*;
import com.gzmu.face.mapper.*;
import com.gzmu.face.service.DepartmentService;
import com.gzmu.face.service.FaceinfoService;
import com.gzmu.face.service.UserService;
import com.gzmu.face.service.VerifypushService;
import com.gzmu.face.tools.HttpResult;
import com.gzmu.face.tools.HttpUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.RowBounds;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@Controller
@RequestMapping("/")
public class FaceController {
    @Autowired
    private VerifypushService verifypushService;
    @Autowired
    private VerifypushMapper verifypushMapper;
    @Autowired
    private FaceinfoMapper faceinfoMapper;
    @Autowired
    private DeviceMapper deviceMapper;
    @Autowired
    private DepartmentMapper departmentMapper;
    @Autowired
    private DepartmentService departmentService;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserService userService;
    @Autowired
    private FaceinfoService faceinfoService;

    @ResponseBody
    @RequestMapping("hello")
    public String Hello(){
        return "Hello, World!";
    }

    @ResponseBody
    @RequestMapping("Subscribe/Verify")
    public Object Verify(HttpServletRequest request) throws IOException {
        Map<Object, Object> map = new HashMap<>();
        String ipaddr = request.getRemoteAddr();
        System.out.println("verifyPush:" +  ipaddr);
        String str, strs = "";

        BufferedReader br = request.getReader();
        while((str = br.readLine()) != null) {
            strs += str;
        }
        String jsonStr = JSON.toJSONString(JSON.parse(strs));
        Map jsonmap = JSON.parseObject(jsonStr, Map.class);
        if (jsonmap != null) {
            Map<String, Object> body = (Map)jsonmap.get( "body" );
            Verifypush verifyPush = new Verifypush();
            verifyPush.setDeviceID( ipaddr );
            float matched = Float.valueOf( body.get( "matched" ).toString() );
            if (matched > 0){
                verifyPush.setName( body.get( "name" ).toString() );
                verifyPush.setPersonID(body.get( "per_id" ).toString());
                verifyPush.setVerfyType( Integer.valueOf( body.get( "role" ).toString() ));
                verifyPush.setSimilarity1(matched );
            }else{
                verifyPush.setName( "访客" );
                verifyPush.setPersonID("1");
                verifyPush.setVerfyType( 0 );
            }

            Date date = new Date();
            SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
            verifyPush.setCreateTime( format.format(date) );
            Double tep = Double.valueOf( body.get( "tep" ).toString());
            verifyPush.setSanpPic( "data:image/jpeg;base64," + body.get( "face_imgdata" ).toString());
            verifyPush.setTemperature( tep );
            if (tep > 37.3){
                verifyPush.setTemperatureAlarm( 1 );
            }else{
                verifyPush.setTemperatureAlarm( 0 );
            }
            verifyPush.setRemark( 0 );
            verifypushMapper.insert( verifyPush );
            map.put("code",200);
            map.put("desc","OK");
        }else {
            map.put("code",201);
            map.put("desc","FAIL");
        }
        return JSONObject.toJSON(map);
    }

    @ResponseBody
    @RequestMapping("/Subscribe/Heartbeat")
    public void Heartbeat(HttpServletRequest request, HttpServletResponse response){
        Map<String, Object> map = new HashMap<>();
        String ipaddr = request.getRemoteAddr();
        Thread thread = Thread.currentThread();
        try {
            thread.sleep(500);
            response.setContentType("text/json;charset=UTF-8");
            PrintWriter writer = response.getWriter();
            if (writer != null) {
                map.put("version",0.2);
                map.put("cmd","create_face");
                map.put("per_id",20200509);
                map.put("per_name","yxb");
                map.put("idcardNum",1234);
                map.put("img_data","img");
                map.put("idcardper","51102419999999171x");
                map.put("per_type",0);
                map.put("usr_type",0);
                writer.write(JSONObject.toJSON(map).toString());
                writer.flush();
                writer.close();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("Heartbeat:" + ipaddr + " :" + JSONObject.toJSON(map));
    }

    @ResponseBody
    @RequestMapping("openDoor")
    public Object openDoor(){
        Map<String, Object> map = new HashMap<>();
        Map<String, Object> params = new HashMap<>();
        Map<String, String> info = new HashMap<>();
        params.put( "operator", "OpenDoor" );
        info.put( "DeviceID", "1370167" );
        info.put( "Chn", "0" );
        info.put( "status", "1" );
        info.put( "msg", "请通行" );
        params.put( "info", info );

        Map<String, String> headParams = new HashMap<>();
        headParams.put( "name", "admin" );
        headParams.put( "passwd", "admin" );
        ObjectMapper mapper = new ObjectMapper();
        try {
            HttpResult result = HttpUtil.doPost( "http://192.168.1.200/action/AddPerson",
                    headParams, mapper.writeValueAsString( params ) );
            map.put("code",result.getStatusCode());
        } catch (Exception e) {
            map.put("code",202);
        }
        System.out.println("======================openDoor");
        return JSONObject.toJSON(map);
    }

    @ResponseBody
    @RequestMapping(value = "/getVerifyPush", produces = "application/json;charset=UTF-8")
    public Object getVerifyPush(@RequestParam Map<String, Object> params) {
        Map <String, Object> map = new HashMap <>();
        int page = Integer.valueOf(params.get( "page" ).toString());
        int limit = Integer.valueOf(params.get( "limit" ).toString());
        if (params.size() > 2){
            String stime = params.get( "stime" ).toString();
            String etime = params.get( "etime" ).toString();
            String idcardNum = params.get( "idcardNum" ).toString();

            if (idcardNum.equals(""))
                params.put("idcardNum", null);
            if (stime.equals("") || etime.equals("") ){
                params.put("stime", null);
                params.put("etime", null);
            }
        }
        params.put("start", (page - 1) * limit);
        params.put("limit", limit);

        List<Verifypush> verifyPushes = verifypushMapper.selectVerify(params);
        int count = verifyPushes.size();

        map.put("data", verifyPushes);
        map.put("count", count);
        map.put("code", 0);
        System.out.println( JSONObject.toJSON(map) );
        System.out.println("======================getVerifyPush");
        return JSONObject.toJSON(map);
    }

    @ResponseBody
    @RequestMapping("/getLastVerifyPush")
    public Object getLastVerifyPush(){
        Map<String, Object> map = verifypushService.getLastVerifyPush();
        System.out.println("======================LoadData");
        return JSONObject.toJSON(map);
    }

    @ResponseBody
    @RequestMapping(value = "/addDepartment", produces = "application/json;charset=UTF-8")
    public Object addDepartment(Department department){
        Map<String, Object> map = new HashMap<>();
        int res = departmentService.insertDepartment( department );
        map.put("code",res);
        System.out.println("======================addDepartment");
        return JSONObject.toJSON(map);
    }

    @ResponseBody
    @RequestMapping(value = "/deleteDepartment", produces = "application/json;charset=UTF-8")
    public Object deleteDepartment(String id){
        Map<String, Object> map = new HashMap<>();
        departmentService.deleteDepartment(id);
        map.put("code",200);
        System.out.println("======================deleteDepartment");
        return JSONObject.toJSON(map);
    }

    @ResponseBody
    @RequestMapping(value = "/getDepartment", produces = "application/json;charset=UTF-8")
    public Object getDepartment(@RequestParam Map<String, Object> params, int page, int limit) {
        Map <String, Object> map = new HashMap <>();
        params.remove( "page" );
        params.remove( "limit" );
        RowBounds rowBounds = new RowBounds( (page - 1) * limit, limit );
        EntityWrapper entityWrapper = new EntityWrapper();
        if (params.size() > 0)
            entityWrapper.like("name", params.get("name").toString());

        List <Department> departments = departmentMapper.selectPage( rowBounds, entityWrapper );
        map.put("data", departments);
        map.put("count", departments.size());
        map.put("code", 0);
        System.out.println("======================getDepartment");
        return JSONObject.toJSON(map);
    }

    @ResponseBody
    @RequestMapping(value = "/addOperator", produces = "application/json;charset=UTF-8")
    public Object addOperator(User user, int role){
        Map<String, Object> map = new HashMap<>();
        user.setRole( role );
        int res = userService.insertOperator( user,role );
        map.put("code",res);
        System.out.println("======================addOperator");
        return JSONObject.toJSON(map);
    }

    @ResponseBody
    @RequestMapping(value = "/deleteOperator", produces = "application/json;charset=UTF-8")
    public Object deleteOperator(String id){
        Map<String, Object> map = new HashMap<>();
        int res = userService.deleteOperator(id);
        map.put("code",res);
        System.out.println("======================deleteOperator");
        return JSONObject.toJSON(map);
    }

    @ResponseBody
    @RequestMapping(value = "/getOperator", produces = "application/json;charset=UTF-8")
    public Object getOperator(int page, int limit) {
        Map <String, Object> map = new HashMap <>();
        RowBounds rowBounds = new RowBounds( (page - 1) * limit, limit );
        List <User> users = userMapper.selectPage( rowBounds, null );
        map.put("data", users);
        map.put("count", users.size());
        map.put("code", 0);
        System.out.println("======================getOperator");
        return JSONObject.toJSON(map);
    }

    @ResponseBody
    @RequestMapping(value = "/addDevice", produces = "application/json;charset=UTF-8")
    public Object addDevice(Device device) {
        Map <String, Object> map = new HashMap <>();
        deviceMapper.insertDevice( device );
        map.put("code",200);
        System.out.println("======================addDevice");
        return JSONObject.toJSON(map);
    }

    @ResponseBody
    @RequestMapping(value = "/deleteDevice", produces = "application/json;charset=UTF-8")
    public Object deleteDevice(String id){
        Map<String, Object> map = new HashMap<>();
        deviceMapper.deleteById( id );
        map.put("code",200);
        System.out.println("======================deleteDevice");
        return JSONObject.toJSON(map);
    }

    @ResponseBody
    @RequestMapping(value = "/getDevice", produces = "application/json;charset=UTF-8")
    public Object getDevice(@RequestParam Map<String, Object> params, int page, int limit) {
        Map <String, Object> map = new HashMap <>();
        params.remove( "page" );
        params.remove( "limit" );
        RowBounds rowBounds = new RowBounds( (page - 1) * limit, limit );
        EntityWrapper entityWrapper = new EntityWrapper();
        if (params.size() > 0)
            entityWrapper.like("Name", params.get("Name").toString());
        List <Device> devices = deviceMapper.selectPage( rowBounds, entityWrapper );
        map.put("data", devices);
        map.put("count",devices.size());
        map.put("code", 0);
        System.out.println("======================getDevice");
        return JSONObject.toJSON(map);
    }

    @ResponseBody
    @RequestMapping(value = "/addPerson", produces = "application/json;charset=UTF-8")
    public Object addPerson(Faceinfo faceinfo){
        Map<String, Object> map = new HashMap<>();
        map.put("code",201);

        JSONArray roomStr = (JSONArray)JSON.parse(faceinfo.getRoom());
        for (int i = 0; i<roomStr.size();i++ ){
            JSONObject room = (JSONObject) roomStr.get(i);
            int id = room.getIntValue( "value" );
            Device device = deviceMapper.selectById(id);
            if (device != null){
                faceinfo.setFaceid( device.getIPAddr() );
                faceinfo.setRemark( 1 );
                faceinfoMapper.insertFaceInfo( faceinfo );
                map.put("code",200);
            }
        }
        System.out.println("======================addPerson");
        return JSONObject.toJSON(map);
    }

    @ResponseBody
    @RequestMapping(value = "/addPersonUp", produces = "application/json;charset=UTF-8")
    public Object addPersonUp(Faceinfo faceinfo){
        Map map = faceinfoService.insertFaceinfoUp( faceinfo );
        System.out.println("addPersonUp:" + JSONObject.toJSON(faceinfo));
        return JSONObject.toJSON(map);
    }

    @ResponseBody
    @RequestMapping(value = "/deletePerson", produces = "application/json;charset=UTF-8")
    public Object deletePerson(String id){
        Map<String, Object> map = faceinfoService.deleteFaceinfoUp(id);
        System.out.println("======================deletePerson");
        return JSONObject.toJSON(map);
    }


    @ResponseBody
    @RequestMapping(value = "/getPerson", produces = "application/json;charset=UTF-8")
    public Object getPerson(@RequestParam Map<String, Object> params, Integer page, Integer limit){
        Map<String, Object> map = new HashMap<>();
        params.remove( "page" );
        params.remove( "limit" );
        EntityWrapper entityWrapper = new EntityWrapper();
        entityWrapper.allEq(params);
        RowBounds rowBounds = new RowBounds( (page - 1) * limit, limit );
        List<Faceinfo> faceinfoList = faceinfoMapper.selectPage( rowBounds, entityWrapper );
        map.put("msg", "success");
        map.put("code",0);
        map.put("count", faceinfoList.size());
        map.put("data",faceinfoList);
        System.out.println("======================getPerson");
        return JSONObject.toJSON(map);
    }

    @ResponseBody
    @RequestMapping(value = "/getVistor", produces = "application/json;charset=UTF-8")
    public Object getVistor(@RequestParam Map<String, String> params,Integer page, Integer limit){
        Map<String, Object> map = new HashMap<>();
        params.remove( "page" );
        params.remove( "limit" );
        RowBounds rowBounds = new RowBounds( (page - 1) * limit, limit );
        List<Faceinfo> faceinfoList = faceinfoMapper.selectPage( rowBounds, null );
        map.put("msg", "success");
        map.put("code",0);
        map.put("count", faceinfoList.size());
        map.put("data",faceinfoList);
        System.out.println("======================getVistor");
        return JSONObject.toJSON(map);
    }

    @ResponseBody
    @PostMapping("/upload")
    public Object upload(@RequestParam("per_name") String per_name, MultipartFile file) {
        Map<String, Object> map = new HashMap<>();
        map.put("code",201);
        if (!file.isEmpty() && per_name != "") {
            String fileName = file.getOriginalFilename();
            // 获取系统文件分隔符
            String type = fileName.substring(fileName.lastIndexOf(".") + 1);
            try {
                File path=new File( ResourceUtils.getURL("classpath:").getPath());
                File uploadPath = new File(path.getAbsolutePath(),"static/upload/") ;

                if (!uploadPath.exists() && !uploadPath.isDirectory()) {
                    System.out.println("创建路径:" + uploadPath);
                    uploadPath.mkdirs();
                }
                String nPath = uploadPath +"/"+ per_name + "." + type;
                File newFile = new File(nPath);
                file.transferTo(newFile);
                System.out.println(per_name + " pictrue upload success");
                map.put("code",200);
                map.put("picURI","/upload/" + per_name + "." + type);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return JSONObject.toJSON(map);
    }

    @RequestMapping("index")
    public String index() {
        System.out.println("======================index");
        return "/index";
    }

    @RequestMapping("logout")
    public String logout() {
        System.out.println("======================logout");
        return "/admin/main";
    }

    @RequestMapping("admin/main")
    public String adminMain() {
        System.out.println("======================adminMain");
        return "/admin/main";
    }

    @RequestMapping("admin/index")
    public String adminIndex() {
        System.out.println("======================adminIndex");
        return "/admin/index";
    }


    @RequestMapping("welcome")
    public String adminWelcome() {
        System.out.println("======================adminWelcome");
        return "/admin/welcome";
    }

    @RequestMapping("yulan")
    public String adminYulan() {
        System.out.println("======================adminYulan");
        return "/admin/yulan";
    }

    @RequestMapping("queryData/query")
    public String queryDataQuery(Model model) {
        List<Department> departments = departmentService.selectList( null );
        model.addAttribute( "departments",  departments);
        System.out.println("======================queryDataQuery");
        return "/admin/queryData/query";
    }

    @RequestMapping("/system/setting")
    public String systemSetting(Model model) {
        String name=(String) SecurityUtils.getSubject().getPrincipal();
        User user = userService.selectOne( new EntityWrapper<User>(  ).eq( "name", name) );
        Department department = departmentService.selectById(user.getParent());
        List<String> roles = userMapper.getRolesNameByUserName(name);
        List<String> permiss = userMapper.getPermissionsNameByUserName(name);
        model.addAttribute( "name", name );
        model.addAttribute( "nickname", user.getNickname() );
        model.addAttribute( "roles", JSONObject.toJSON(roles) );
        model.addAttribute( "permiss", JSONObject.toJSON(permiss) );
        model.addAttribute( "dmname", department.getName() );
        model.addAttribute( "address", department.getAddress() );
        model.addAttribute( "situation", department.getSituation() );
        model.addAttribute( "principal", department.getPrincipal() );
        model.addAttribute( "telnum", department.getTelnum() );
        model.addAttribute( "updatetime", department.getUpdatetime() );

        System.out.println("======================systemSetting");
        return "/admin/system/setting";
    }

    @RequestMapping("enterprise/info")
    public String enterpriseInfo() {
        System.out.println("======================enterpriseInfo");
        return "/admin/enterprise/info";
    }

    @RequiresPermissions({"/enterprise/addDepartment"})
    @RequestMapping("enterprise/addDepartment")
    public String enterpriseAddDepartment(String id, Model model) {
        if (id != null){
            Department department = departmentService.selectById(id);
            model.addAttribute( "department",  department);
        }
        List<Department> departments = departmentService.selectList( null );
        model.addAttribute( "departments",  departments);
        System.out.println("======================enterpriseAddDepartment");
        return "/admin/enterprise/addDepartment";
    }

    @RequiresPermissions({"/enterprise/departmentManage"})
    @RequestMapping("enterprise/departmentManage")
    public String enterpriseDepartmentManage() {
        System.out.println("======================enterpriseDepartmentManage");
        return "/admin/enterprise/departmentManage";
    }

    @RequiresPermissions({"/enterprise/operator"})
    @RequestMapping("enterprise/operator")
    public String enterpriseOperator() {
        System.out.println("======================enterpriseOperator");
        return "/admin/enterprise/operator";
    }

    @RequiresPermissions({"/enterprise/addOperator"})
    @RequestMapping("enterprise/addOperator")
    public String enterpriseAddOperator(String id, Model model) {
        if (id != null) {
            User user = userMapper.selectById( id );
            model.addAttribute( "user" ,user);
        }
        List<Department> departments = departmentService.selectList( null );
        model.addAttribute( "departments",  departments);
        System.out.println("======================enterpriseAddOperator");
        return "/admin/enterprise/addOperator";
    }

    @RequiresPermissions({"/perManage/addPerson"})
    @RequestMapping("perManage/addPerson")
    public String perManageAddPerson(String id, Model model) {
        if (id != null) {
            Faceinfo faceinfo = faceinfoMapper.selectById( id );
            model.addAttribute( "faceinfo" ,faceinfo);
        }
        List<Department> departments = departmentService.selectList( null );
        List<Device> devices  = deviceMapper.selectList( null );
        model.addAttribute( "departments",  departments);
        model.addAttribute( "devices",  devices);
        System.out.println("======================perManageAddPerson");
        return "/admin/perManage/addPerson";
    }

    @RequestMapping("/perManage/editAuth")
    public String perManageEditAuth() {
        System.out.println("======================perManageEditAuth");
        return "/admin/perManage/editAuth";
    }

    @RequestMapping("perManage/personManage")
    public String perManagePersonManage(Model model) {
        List<Department> departments = departmentMapper.selectList( null );
        model.addAttribute( "departments",departments );
        System.out.println("======================perManagePersonManage");
        return "/admin/perManage/personManage";
    }

    @RequestMapping("perManage/editPerAuth")
    public String perManageEditPerAuth() {
        System.out.println("======================perManageEditPerAuth");
        return "/admin/perManage/editPerAuth";
    }

    @RequestMapping("perManage/perSynchro")
    public String perManagePerSynchro() {
        System.out.println("======================perManagePerSynchro");
        return "/admin/perManage/perSynchro";
    }

    @RequestMapping("visitorManage/visitorSynchro")
    public String visitorManageVisitorSynchro() {
        System.out.println("======================visitorManageVisitorSynchro");
        return "/admin/visitorManage/visitorSynchro";
    }

    @RequestMapping("visitorManage/addVistor")
    public String visitorManageAddVistor(String id, Model model) {
        if (id != null) {
            Faceinfo faceinfo = faceinfoMapper.selectById( id );
            model.addAttribute( "faceinfo" ,faceinfo);
        }
        List<Device> devices  = deviceMapper.selectList( null );
        model.addAttribute( "devices",  devices);
        System.out.println("======================visitorManageAddVistor");
        return "/admin/visitorManage/addVistor";
    }

    @RequestMapping("visitorManage/visitorFile")
    public String visitorManageVisitorFile() {
        System.out.println("======================visitorManageVisitorFile");
        return "/admin/visitorManage/visitorFile";
    }

    @RequiresPermissions({"/device/deviceManage"})
    @RequestMapping("/device/deviceManage")
    public String deviceDeviceManage() {
        System.out.println("======================deviceDeviceManage");
        return "/admin/device/deviceManage";
    }

    @RequestMapping("device/personList")
    public String devicePersonList(Model model) {
        List<Device> devices  = deviceMapper.selectList( null );
        model.addAttribute( "devices",  devices);
        System.out.println("======================deviceInterLister");
        return "/admin/device/personList";
    }

    @RequiresPermissions({"/device/addDevice"})
    @RequestMapping("/device/addDevice")
    public String deviceAddDevice(String id, Model model) {
        if (id != null) {
            Device device = deviceMapper.selectById( id );
            model.addAttribute( "device" ,device);
        }
        System.out.println("======================deviceAddDevice");
        return "/admin/device/addDevice";
    }

    @RequestMapping("/attendance/report")
    public String attendanceReport() {
        System.out.println("======================attendanceReport");
        return "/admin/attendance/report";
    }
}

